package com.hrt.datasender.process.strategy.hj212;

import com.btcode.db.result.Row;
import com.btcode.db.sqlparameter.SQLParameterList;
import com.hrt.datasender.datadao.model.BcSendPlatformDataStrategyModel;
import com.hrt.datasender.datadao.model.BcSendPlatformModel;
import com.hrt.datasender.datadao.service.BCSiteService;
import com.hrt.datasender.datadao.service.BcSendPlatformDataStrategyService;
import com.hrt.datasender.datastorage.strategy.IStorageStrategy;
import com.hrt.datasender.datastorage.strategy.StrategyLoader;
import com.hrt.datasender.datastorage.strategy.monitordata.MonitorDataStrategy;
import com.hrt.datasender.mq.MqKit;
import com.hrt.datasender.mq.model.PacketModel;
import com.hrt.datasender.process.indentity.hj212.MessageModel;
import com.hrt.datasender.process.strategy.IProcessStrategy;
import com.hrt.datasender.process.strategy.ProcessStrategyLoader;
import com.hrt.datasender.process.strategy.hj212.util.CRCUtil;
import com.hrt.datasender.process.strategy.hj212.util.DataType;
import com.hrt.datasender.process.strategy.hj212.util.StrategyUtil;
import com.hrt.datasender.web.WebMain;
import com.hrt.datasender.web.operInfo.OperInfoService;
import com.hrt.db.DBManager;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

public abstract class ProcessStrategyMonitorData implements IProcessStrategy {
    
    private final int dataLengthFormat = 4;

    public abstract DataType getDataType();

    /**
     * 数据发送时QN获取的是datatime的时间，9014命令收到反馈修改datatime是根据发送时的QN来
     * ，如果QN和datatime相同会导致时间并没有变化，因此在这里+10000
     * = 10S 使时间改变
     */
    @Override
    public Object packet(List<Row> data, BcSendPlatformModel sendPlatform) {
        final long timeDiffer = 10000;
        String msg = getCommandPacket(sendPlatform, getDataType(), data, timeDiffer);
        return msg;
    }

    /**
     * 补传数据QN加上三年的时间
     */
    @Override
    public Object packetReissue(List<Row> data, BcSendPlatformModel sendPlatform) {
        final long timeDiffer = 94608000000L;
        String msg = getCommandPacket(sendPlatform, getDataType(), data, timeDiffer);
        return msg;
    }

    /**
     * 
     * <pre>
     * 判断数据协议，然后打包数据
     * </pre>
     * 
     * @author FAN
     * @date 2018年9月13日上午10:09:05
     * @param platform
     * @param rowList
     * @param dataType
     * @return
     */
    public String getPacketCpStr(BcSendPlatformModel platform, List<Row> rowList, DataType dataType) {

        DateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");

        if (rowList.size() < 1) {
            return null;
        }

        long date;
        if("mysql".equals(WebMain.DBTYPE)){
            date = rowList.get(0).getDate("DATATIME").getTime();
        }
        else{
           date = (long) rowList.get(0).get("DATATIME");
        }

        StringBuffer sb = new StringBuffer("DataTime=" + sdf.format(new Date(date)) + ";");
        String paramCodePro = null;
        String acc = null;
        String st = getSTValue();
        List<String> flowHandlePlat = new ArrayList<>();
        flowHandlePlat.add("国发平台");
        for (Row row : rowList) {
            String pramCodeBus = String.valueOf(row.get("PARAM_CODE_BUS"));
            String measRe = String.valueOf(row.get("MEAS_RE"));
            String measPl = String.valueOf(row.get("MEAS_PL"));
            String flag = String.valueOf(row.get("FLAG"));

            try {
                if (measRe == null) {
                    continue;
                }

                paramCodePro = getParamMap212Value(pramCodeBus,platform.getTransportProtocolId());

                if (measRe.equals("null")) {
                    measRe = "";
                }

                if (measPl==null||measPl.equals("null")) {
                    measPl = "";
                }

                // 去除科学计数法
                if (measRe != null && !"".equals(measRe)) {
                    BigDecimal measReStr = new BigDecimal(measRe.toString());
                    measRe = measReStr.toString();
                }

                //流量特殊处理
                if(flowHandlePlat.contains(platform.getTransportProtocolName())){
                    if ("B01TOTAL".equals(paramCodePro)){
                        acc = "B01-Cou=" + measRe + ",";
                        continue;
                    }
                    else if("AIR_B01TOTAL".equals(paramCodePro)){
                        acc = "B02-Cou=" + measRe + ",";
                        continue;
                    }
                }

                if ("2011".equals(dataType.getCn())) {
                    sb.append(paramCodePro + "-Rtd=" + measRe + ",");
                }
                else {
                    if(!"B01".equals(paramCodePro)&&!"B02".equals(paramCodePro)){
                        sb.append(paramCodePro + "-Cou=" + measPl + ",");
                    }

                    sb.append(paramCodePro + "-Min=" + measRe + ",");
                    sb.append(paramCodePro + "-Avg=" + measRe + ",");
                    sb.append(paramCodePro + "-Max=" + measRe + ",");
                }
                sb.append(paramCodePro + "-Flag=" + flag + ";");
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }

        if(flowHandlePlat.contains(platform.getTransportProtocolName())&&acc!=null){
            if(sb.indexOf("B01-Min")>0){
                sb.insert(sb.indexOf("B01-Min"), acc);
            }
            else if(sb.indexOf("B02-Min")>0){
                sb.insert(sb.indexOf("B02-Min"), acc);
            }
        }
        sb.setLength(sb.length() - 1);
        return sb.toString();
    }

    public String getCommandPacket(BcSendPlatformModel platform, DataType dataType, List<Row> data, long timeDiffer) {

        SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        String cp = getPacketCpStr(platform, data, dataType);
        StringBuilder strBuilder = new StringBuilder();

        if (data.size() < 1) {
            return null;
        }

        long date;
        if("mysql".equals(WebMain.DBTYPE)){
            date = data.get(0).getDate("DATATIME").getTime();
        }
        else{
            date = (long) data.get(0).get("DATATIME");
        }

        strBuilder.append("QN=" + sf.format(new Date(date + timeDiffer)) + ";");
        strBuilder.append("ST=" + BCSiteService.getInstance().getModel().getSystemType() + ";");
        strBuilder.append("Flag=1;");
        strBuilder.append("CN=" + dataType.getCn() + ";");
        strBuilder.append("PW=123456;");
        strBuilder.append("MN=" + platform.getMn() + ";");
        strBuilder.append("CP=&&" + cp + "&&");

        String crcStr = CRCUtil.calcCRC(strBuilder.toString());

        String dataLength = strBuilder.length() + "";
        while (dataLength.length() < dataLengthFormat) {
            dataLength = "0" + dataLength;
        }

        strBuilder.insert(0, "##" + dataLength);

        strBuilder.append(crcStr + "\r\n");
        return strBuilder.toString();
    }

    /**
     * 212-2017版本，响应平台取数据命令
     * 0.返回请求应答
     * 1.获取beginTime和endTime
     * 2.获取数据构造报文，进行数据发送
     * 3.返回执行结果
     * @param data
     * @param sendPlatform
     */
    @Override
    public void decode(MessageModel data, BcSendPlatformModel sendPlatform) {
        try{
            String msg = data.getMsg() + "";
            StrategyUtil.responseMsg(sendPlatform,msg,"0","");

            /**
             * 获取cp内容
             */
            String cp = MessagePraser.getCP(msg);
            HashMap<String, String> cpDataValue = new HashMap<>();
            String cpParmValueStrs[] = cp.split(";");
            for (String cpParmValueStr : cpParmValueStrs) {
                String[] cpParmValue = cpParmValueStr.split("=");
                if (cpParmValue.length < 2) {
                    continue;
                }
                cpDataValue.put(cpParmValue[0], cpParmValue[1]);
            }
            String start = cpDataValue.get("BeginTime");
            String end = cpDataValue.get("EndTime");

            /**
             * 获取对应的数据策略，根据平台ID及processID
             */
            String platFormID = sendPlatform.getPlatformId();
            String processStrategyId  = this.getClass().getName().replace("com.hrt.datasender.process.strategy.","");
            BcSendPlatformDataStrategyModel model = new BcSendPlatformDataStrategyModel();
            model.setPlatformId(platFormID);
            model.setProcessStrategyId(processStrategyId);
            List<BcSendPlatformDataStrategyModel> models =  BcSendPlatformDataStrategyService.getInstance().getModels(model);
            String storageStrategyId = models.get(0).getStorageStrategyId();
            IStorageStrategy strategy = StrategyLoader.getInstance().getStrategyById(storageStrategyId);
            MonitorDataStrategy mdStrategy = (MonitorDataStrategy) strategy;

            /**
             * 根据开始时间与结束时间,获取补传数据时间
             */
            SimpleDateFormat sdf= new SimpleDateFormat("yyyyMMddHHmmss");
            Date startDate = sdf.parse(start);
            Date endDate = sdf.parse(end);
            long startTime  = startDate.getTime();
            long endTime  = endDate.getTime();
            long timeInterval = (long)mdStrategy.getDataInterval() * 1000;
            while(startTime <= endTime) {
                List<Row> sendData = mdStrategy.getData(sendPlatform, startTime,endTime);
                if (sendData == null || sendData.size() <= 0) {
                    startTime += timeInterval;
                    continue;
                }

                IProcessStrategy processStrategy = ProcessStrategyLoader.getInstance().getStrategyById(platFormID,
                        processStrategyId);
                Object packetMsg = processStrategy.packetReissue(sendData, sendPlatform);
                PacketModel packetModel = new PacketModel();
                packetModel.setIp(sendPlatform.getIp());
                packetModel.setPort(sendPlatform.getPort());
                packetModel.setMn(sendPlatform.getMn());
                packetModel.setMsg(packetMsg);

                MqKit.productMsgToRecriminateMQ(packetModel);
                startTime += timeInterval;
            }

            /**
             * 返回执行结果
             */
            StrategyUtil.responseMsg(sendPlatform,msg,"1","1");
        }
        catch (Exception e){
            OperInfoService.getInstance().error(e,null);
        }
    }

    private String getParamMap212Value(String key,String protocolID) {
        String sql = "SELECT PARAM_CODE_PRO FROM BC_PARAM_MAP_212" +
                " WHERE PARAM_CODE_BUS=@PARAM_CODE_BUS" +
                " AND TRANSPORT_PROTOCOL_ID=@TRANSPORT_PROTOCOL_ID";
        SQLParameterList pc = new SQLParameterList();
        pc.put("PARAM_CODE_BUS", key);
        pc.put("TRANSPORT_PROTOCOL_ID", protocolID);
        String code = (String) DBManager.getDataExecuter().queryScalar(sql, pc);
        return code;
    }

    /**
     * 
     * <pre>
     * 判断站点类型
     * </pre>
     * 
     * @author FAN
     * @date 2018年9月17日下午3:15:49
     * @return
     */
    private String getSTValue() {
        String sql = "SELECT SYSTEM_TYPE FROM BC_SITE";
        String code = (String) DBManager.getDataExecuter().queryScalar(sql, null);
        return code;
    }
}
